package cn.agiledata.bank.linkbank.impl.cmbc;

import java.math.BigDecimal;
import java.util.Date;

import cn.agiledata.bank.common.util.DateUtil;
import cn.agiledata.bank.linkbank.exception.LinkBankException;
import cn.agiledata.bank.linkbank.impl.AbstractBankNetPayRequest;
import cn.agiledata.bank.linkbank.impl.AbstractBankPayRequest;
import cn.agiledata.bank.linkbank.logic.DigitalSignGeneratable;
import cn.agiledata.bank.linkbank.logic.OrderIdTransformer;

/**
 * 中国民生银行网上银行支付请求
 * 
 * @author jessik
 * 
 */
public final class CmbcNetPayRequest extends AbstractBankNetPayRequest
		implements DigitalSignGeneratable {
	private static final String[] REQUEST_KEYS = { CmbcNetConstant.BIll_NO, CmbcNetConstant.TX_AMT,
			CmbcNetConstant.PAYER_CURR, CmbcNetConstant.TX_DATE,
			CmbcNetConstant.TX_TIME, CmbcNetConstant.CORP_ID,
			CmbcNetConstant.CORP_NAME, CmbcNetConstant.BILL_REMARK_1,
			CmbcNetConstant.BILL_REMARK_2, CmbcNetConstant.CORP_RET_TYPE,
			CmbcNetConstant.RET_URL, CmbcNetConstant.MAC };
	
	private String certFilePath;

	private String keyFilePath;

	private OrderIdTransformer orderIdTransformer;

	public CmbcNetPayRequest() {
		super();
		init();
	}

	private void init() {
		this.setParameter(CmbcNetConstant.PAYER_CURR,
				CmbcNetConstant.PAYER_CURR_CNY);// 货币类型：人民币
		this.setParameter(CmbcNetConstant.CORP_RET_TYPE,
				CmbcNetConstant.CORP_RET_TYPE_0);// 是否实时返回标志：即时返回
		this.setParameter(CmbcNetConstant.BILL_REMARK_2, "");// 注释2为空
		this.setParameter(CmbcNetConstant.MAC, "");// MAC为空
	}

	public void setCertFilePath(String certFilePath) {
		this.certFilePath = certFilePath;
	}

	public void setKeyFilePath(String keyFilePath) {
		this.keyFilePath = keyFilePath;
	}

	protected AbstractBankPayRequest getCopiedInstance() {
		CmbcNetPayRequest request = new CmbcNetPayRequest();
		request.certFilePath = this.certFilePath;
		request.keyFilePath = this.keyFilePath;
		request.orderIdTransformer = this.orderIdTransformer;
		return request;
	}

	private OrderIdTransformer getOrderIdTransformer() {// 订单生成器
		if (this.orderIdTransformer == null) {
			this.orderIdTransformer = new CmbcOrderIdTransformer(
					getMerchantId());
		}
		return this.orderIdTransformer;
	}

	public void setOrderId(String orderId) {// 定单号（商户号（5位）＋商户自定义序号（15位））
		this.setParameter(CmbcNetConstant.BIll_NO, getOrderIdTransformer()
				.transId2OrderId(orderId));
	}

	public void setAmount(BigDecimal amount) {// 金额
		this
				.setParameter(CmbcNetConstant.TX_AMT, amount.setScale(2)
						.toString());
	}

	public void setDate(Date date) { // 设置订单时间和日期
		String dateValue = DateUtil.date2String(date,
				CmbcNetConstant.TX_DATE_FORMAT);
		setParameter(CmbcNetConstant.TX_DATE, dateValue);
		String timeValue = DateUtil.date2String(date,
				CmbcNetConstant.TX_TIME_FORMAT);
		setParameter(CmbcNetConstant.TX_TIME, timeValue);

	}

	public void setMerchantId(String merchantId) { // 商户号（5位，银行事先分配）
		this.setParameter(CmbcNetConstant.CORP_ID, merchantId);
	}

	public String getMerchantId() { // 商户号（5位，银行事先分配）
		return this.getParameter(CmbcNetConstant.CORP_ID);
	}

	public void setMerchantName(String merchantName) {// 商户名称
		this.setParameter(CmbcNetConstant.CORP_NAME, merchantName);
	}

	public void setRemark(String remark) {// 注释（可空）
		this.setParameter(CmbcNetConstant.BILL_REMARK_1, remark);
	}

	public String getMerchantUrl() {// 返回url
		return getParameter(CmbcNetConstant.RET_URL);
	}

	public void setMerchantUrl(String merchantUrl) {
		this.setParameter(CmbcNetConstant.RET_URL, merchantUrl);

	}

	public String generateDigitalSign(String cryptoKey)
			throws LinkBankException {
		String[] keys = REQUEST_KEYS;
		String digitalSign = CmbcUtils.getDigitalSign(this.getParameters(), keys, cryptoKey,
				this.certFilePath,this.keyFilePath);
		this.setParameter(CmbcNetConstant.ORDER_INFO, digitalSign);
		return digitalSign;
	}
	
	public String getCryptoKeyDescription() {
		return "";
	}

	public boolean validateCryptoKey(String cryptoKey) {
		return true;
	}

}
